﻿using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

namespace org.theGecko.Utilities.MefMvc
{
    /// <summary>
    /// View engine extending standard view engine to inject site master and register view paths to be scanned
    /// </summary>
    public class MefViewEngine : WebFormViewEngine
    {
        private readonly string _defaultMaster;

        public MefViewEngine(string pluginPath, IEnumerable<IPluginRegistration> plugins, string defaultMaster)
        {
            _defaultMaster = defaultMaster;
            CreateViewLocations(pluginPath, plugins);
        }

        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            // Set default master page - não é preciso setar uma masterpage
            /*if (string.IsNullOrWhiteSpace(masterName))
            {
                masterName = _defaultMaster;
            }*/

            // Ensure name is correct
            if (masterName.ToLowerInvariant().EndsWith(".master"))
            {
                masterName = masterName.ToLowerInvariant().Replace(".master", string.Empty);
            }

            return base.FindView(controllerContext, viewName, masterName, useCache);
        }

        protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
        {
            // If view isn't .aspx, remove master page
            if (!viewPath.ToLowerInvariant().EndsWith(".aspx"))
            {
                masterPath = string.Empty;
            }

            return new WebFormView(viewPath, masterPath);
        }

        #region Helper Methods

        private void CreateViewLocations(string pluginPath, IEnumerable<IPluginRegistration> plugins)
        {
            IList<string> viewLocations = new List<string>();
            IList<string> masterLocations = new List<string>();
            string pluginLocation;

            
            foreach (IPluginRegistration plugin in plugins)
            {

                //mudada a estrutura do caminho
                pluginLocation = string.Format("~/{0}/{1}/Views/", pluginPath, plugin.PluginName);
                AddViewLocation(viewLocations, pluginLocation);
                AddMasterLocation(masterLocations, pluginLocation);

            }

            pluginLocation = "~/Views/";
            AddViewLocation(viewLocations, pluginLocation);

            ViewLocationFormats = viewLocations.ToArray();
            PartialViewLocationFormats = viewLocations.ToArray();
            MasterLocationFormats = masterLocations.ToArray();

            AreaViewLocationFormats = new[] {
                "~/" + pluginPath + "/Views/{2}/{1}/{0}.aspx",
                "~/" + pluginPath + "/Views/{2}/{1}/{0}.ascx",
                "~/" + pluginPath + "/Views/{2}/Shared/{0}.aspx",
                "~/" + pluginPath + "/Views/{2}/Shared/{0}.ascx",
            };

            AreaPartialViewLocationFormats = AreaViewLocationFormats;

            AreaMasterLocationFormats = new[] {
                "~/" + pluginPath + "/Views/{2}/{1}/{0}.master",
                "~/" + pluginPath + "/Views/{2}/Shared/{0}.master",
            };
        }

        private static void AddViewLocation(IList<string> viewLocations, string pluginLocation)
        {
            viewLocations.Add(pluginLocation + "{1}/{0}.aspx");
            viewLocations.Add(pluginLocation + "{1}/{0}.ascx");
            viewLocations.Add(pluginLocation + "Shared/{0}.aspx");
            viewLocations.Add(pluginLocation + "Shared/{0}.ascx");
        }

        private static void AddMasterLocation(IList<string> viewLocations, string pluginLocation)
        {
            viewLocations.Add(pluginLocation + "{1}/{0}.master");
            viewLocations.Add(pluginLocation + "Shared/{0}.master");
        }

        public static string PathPlugin()
        {
            return "/{0}/{1}/Views/";
        }
        #endregion
    }
}